Translate secure/non-secure virtual addresses
authorVarun Wadekar <[email protected]>
Fri, 13 Mar 2015 09:29:03 +0000 (14:59 +0530)
committerVarun Wadekar <[email protected]>
Tue, 31 Mar 2015 04:36:51 +0000 (10:06 +0530)
This patch adds functionality to translate virtual addresses from
secure or non-secure worlds. This functionality helps Trusted Apps
to share virtual addresses directly and allows the NS world to
pass virtual addresses to TLK directly.

Change-Id: I77b0892963e0e839c448b5d0532920fb7e54dc8e
Signed-off-by: Varun Wadekar <[email protected]>
include/bl32/payloads/tlk.h
include/lib/aarch64/arch_helpers.h
services/spd/tlkd/tlkd_common.c
services/spd/tlkd/tlkd_main.c
services/spd/tlkd/tlkd_private.h

index b6299a8b5997a229821c41d11c058f3426cf7b4e..0ad1ac06e242ec13aae36753e9bc396339d6a4b6 100644 (file)
@@ -48,6 +48,7 @@
  */
 #define TLK_REQUEST_DONE       (0x32000001 | (1 << 31))
 #define TLK_ENTRY_DONE         (0x32000003 | (1 << 31))
+#define TLK_VA_TRANSLATE       (0x32000004 | (1 << 31))
 #define TLK_FID_SHARED_MEMBUF  (0x32000005 | (1 << 31))
 
 /*
index 65941e6cfc9b0aee45870760ddcd55075e4eacd0..ceb88e47729a88462e97176a0667a6a62e14b84d 100644 (file)
@@ -136,6 +136,14 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, civac)
 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, cvau)
 DEFINE_SYSOP_TYPE_PARAM_FUNC(dc, zva)
 
+/*******************************************************************************
+ * Address translation accessor prototypes
+ ******************************************************************************/
+DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w)
+
 void flush_dcache_range(uint64_t, uint64_t);
 void inv_dcache_range(uint64_t, uint64_t);
 void dcsw_op_louis(uint32_t);
@@ -160,6 +168,7 @@ DEFINE_SYSREG_WRITE_CONST_FUNC(daifclr)
 #define disable_serror()               write_daifset(DAIF_ABT_BIT)
 #define disable_debug_exceptions()     write_daifset(DAIF_DBG_BIT)
 
+DEFINE_SYSREG_READ_FUNC(par_el1)
 DEFINE_SYSREG_READ_FUNC(id_pfr1_el1)
 DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
 DEFINE_SYSREG_READ_FUNC(CurrentEl)
index 5944174d576a964a31b427bd8f94002aa1310165..b19e27d06dfc116dad8c11dbdfd1b10eb55d2276 100644 (file)
 #include <string.h>
 #include "tlkd_private.h"
 
+#define AT_MASK                3
+
+/*******************************************************************************
+ * This function helps the SP to translate NS/S virtual addresses.
+ ******************************************************************************/
+uint64_t tlkd_va_translate(uintptr_t va, int type)
+{
+       uint64_t pa;
+
+       if (type & TLK_TRANSLATE_NS_VADDR) {
+
+               /* save secure context */
+               cm_el1_sysregs_context_save(SECURE);
+
+               /* restore non-secure context */
+               cm_el1_sysregs_context_restore(NON_SECURE);
+
+               /* switch NS bit to start using 64-bit, non-secure mappings */
+               write_scr(cm_get_scr_el3(NON_SECURE));
+               isb();
+       }
+
+       int at = type & AT_MASK;
+       switch (at) {
+       case 0:
+               ats12e1r(va);
+               break;
+       case 1:
+               ats12e1w(va);
+               break;
+       case 2:
+               ats12e0r(va);
+               break;
+       case 3:
+               ats12e0w(va);
+               break;
+       default:
+               assert(0);
+       }
+
+       /* get the (NS/S) physical address */
+       isb();
+       pa = read_par_el1();
+
+       /* Restore secure state */
+       if (type & TLK_TRANSLATE_NS_VADDR) {
+
+               /* restore secure context */
+               cm_el1_sysregs_context_restore(SECURE);
+
+               /* switch NS bit to start using 32-bit, secure mappings */
+               write_scr(cm_get_scr_el3(SECURE));
+               isb();
+       }
+
+       return pa;
+}
+
 /*******************************************************************************
  * Given a secure payload entrypoint, register width, cpu id & pointer to a
  * context data structure, this function will create a secure context ready for
index 8d2d437ed572d0d5363f22ec417e440314a272a7..eb6b89de5ad12e72a32687856357b8e3d1bd54d3 100644 (file)
@@ -188,6 +188,7 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid,
 {
        cpu_context_t *ns_cpu_context;
        uint32_t ns;
+       uint64_t vaddr, type, par;
 
        /* Passing a NULL context is a critical programming error */
        assert(handle);
@@ -246,6 +247,24 @@ uint64_t tlkd_smc_handler(uint32_t smc_fid,
                cm_set_next_eret_context(SECURE);
                SMC_RET0(&tlk_ctx.cpu_ctx);
 
+       /*
+        * Translate NS/EL1-S virtual addresses
+        */
+       case TLK_VA_TRANSLATE:
+               if (ns || !tlk_args_results_buf)
+                       SMC_RET1(handle, SMC_UNK);
+
+               /* virtual address and type: ns/s */
+               vaddr = tlk_args_results_buf->args[0];
+               type = tlk_args_results_buf->args[1];
+
+               par = tlkd_va_translate(vaddr, type);
+
+               /* Save PA for use by the SP on return */
+               store_tlk_args_results(par, 0, 0, 0);
+
+               SMC_RET0(handle);
+
        /*
         * This is a request from the SP to mark completion of
         * a standard function ID.
index 88e720a7e92cc022fab19f9d593e11e59410c789..271c24ca2bf05af289b54a63ed98f017356211f3 100644 (file)
                                         ~(STD_SMC_ACTIVE_FLAG_MASK           \
                                           << STD_SMC_ACTIVE_FLAG_SHIFT))
 
+/*******************************************************************************
+ * Translate virtual address received from the NS world
+ ******************************************************************************/
+#define TLK_TRANSLATE_NS_VADDR         4
+
 /*******************************************************************************
  * Secure Payload execution state information i.e. aarch32 or aarch64
  ******************************************************************************/
@@ -124,6 +129,7 @@ typedef struct tlk_context {
 /*******************************************************************************
  * Function & Data prototypes
  ******************************************************************************/
+uint64_t tlkd_va_translate(uintptr_t va, int type);
 uint64_t tlkd_enter_sp(uint64_t *c_rt_ctx);
 void __dead2 tlkd_exit_sp(uint64_t c_rt_ctx, uint64_t ret);
 uint64_t tlkd_synchronous_sp_entry(tlk_context_t *tlk_ctx);